import datetime
from collections import OrderedDict

from django.shortcuts import render

# Create your views here.
from rest_framework.permissions import IsAdminUser, AllowAny, IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet, GenericViewSet

from Libraries.settings import HAYSTACK_SEARCH_RESULTS_PER_PAGE
from apps.books.serializers import BookInfoModelSerializer, CategoryModelSerializer, HistoryModelSerializer
from apps.books.models import BookInfo, Category, BookHistory
from utils.page import PageNum
from django.shortcuts import get_object_or_404

from utils.response import ReturnMsg


class BookModelViewSet(ModelViewSet):
    # queryset = BookInfo.objects.all()
    permission_classes = [IsAdminUser, ]

    serializer_class = BookInfoModelSerializer
    pagination_class = PageNum

    def get_queryset(self):
        category = self.request.query_params.get("category")
        if category:
            return BookInfo.objects.filter(category_id=category)
        else:
            return BookInfo.objects.all()

    def create(self, request, *args, **kwargs):
        response = super().create(request, args, kwargs)
        return Response(ReturnMsg(data=response.data).dict(), status=response.status_code)

    def retrieve(self, request, *args, **kwargs):
        response = super().retrieve(request, args, kwargs)
        return Response(ReturnMsg(data=response.data).dict(), status=response.status_code)

    def update(self, request, *args, **kwargs):
        response = super().update(request, args, kwargs)
        return Response(ReturnMsg(data=response.data).dict(), status=response.status_code)

    def destroy(self, request, *args, **kwargs):
        response = super().destroy(request, args, kwargs)
        return Response(ReturnMsg().dict(), status=response.status_code)


class BookReadOnlyModelViewSet(ReadOnlyModelViewSet):
    # queryset = BookInfo.objects.all()
    permission_classes = [IsAuthenticated, ]

    serializer_class = BookInfoModelSerializer
    pagination_class = PageNum

    def get_queryset(self):
        category = self.request.query_params.get("category")
        if category:
            return BookInfo.objects.filter(category_id=category)
        else:
            return BookInfo.objects.all()


class CategoryModelViewSet(ReadOnlyModelViewSet):
    permission_classes = [AllowAny, ]

    queryset = Category.objects.all()
    serializer_class = CategoryModelSerializer


class HistoryModelViewSet(ModelViewSet):
    permission_classes = [IsAdminUser, ]

    def get_queryset(self):
        book = self.request.query_params.get("book")
        user = self.request.query_params.get("user")
        if book and user:
            return BookHistory.objects.filter(book_id=book, user_id=user)
        if book and not user:
            return BookHistory.objects.filter(book_id=book)
        if not book and user:
            return BookHistory.objects.filter(user_id=user)
        return BookHistory.objects.all()

    def create(self, request, *args, **kwargs):
        response = super().create(request, args, kwargs)
        return Response(ReturnMsg(data=response.data).dict(), status=response.status_code)

    def retrieve(self, request, *args, **kwargs):
        response = super().retrieve(request, args, kwargs)
        return Response(ReturnMsg(data=response.data).dict(), status=response.status_code)

    def update(self, request, *args, **kwargs):
        response = super().update(request, args, kwargs)
        return Response(ReturnMsg(data=response.data).dict(), status=response.status_code)

    def destroy(self, request, *args, **kwargs):
        response = super().destroy(request, args, kwargs)
        return Response(ReturnMsg().dict(), status=response.status_code)

    serializer_class = HistoryModelSerializer


class ReadOnlyHistoryModelViewSet(ReadOnlyModelViewSet):
    permission_classes = [IsAuthenticated, ]

    def get_queryset(self):
        return BookHistory.objects.filter(user_id=self.request.user.id)

    serializer_class = HistoryModelSerializer


from haystack.views import SearchView
from django.http import JsonResponse


class MySearchView(SearchView):
    '''重写SearchView类'''

    def create_response(self):
        # 获取搜索结果
        context = self.get_context()

        data_list = []
        for book in context['page'].object_list:
            book.object: BookInfo
            data_list.append({
                'id': book.object.id,
                'title': book.object.title,
                'author': book.object.author,
                'number': book.object.number,
                'category': book.object.category_id,
                'cover': book.object.cover,
                'intro': book.object.intro,
            })

        # 拼接参数, 返回
        return JsonResponse({
            "books": data_list,
            'num_pages': context['page'].paginator.num_pages,
            'page_size': HAYSTACK_SEARCH_RESULTS_PER_PAGE,
            'count': context['page'].paginator.count,
        }, safe=False, json_dumps_params={'ensure_ascii': False})


class BorrowAPIView(APIView):
    def post(self, request):
        data = request.data
        book_id = data.get('book')
        book = BookInfo.objects.filter(id=book_id)
        if book.count() < 1:
            return Response({
                "code": 4000,
                "type": "请求参数非法",
                "message": "书籍不存在"
            })
        book = book[0]
        if book.number > 0:
            book.number = book.number - 1
            book.save()
        else:
            return Response({
                "code": 4000,
                "type": "请求参数非法",
                "message": "书籍已被全部借阅"
            })
        try:
            BookHistory.objects.create(book_id=book_id, user_id=request.user.id)
            request.user.borrowed -= 1
            request.user.save()
        except:
            return Response({
                "code": 5000,
                "type": "服务器异常",
                "message": "借阅记录创建出错"
            }, status=500)
        return Response({
            "code": 0,
            "type": "访问成功",
            "message": "借书成功"
        })


class ReturnAPIView(APIView):
    def post(self, request):
        data = request.data
        history_id = data.get('history')
        history = BookHistory.objects.get(id=history_id)
        if not history:
            return Response({
                "code": 4000,
                "type": "请求参数非法",
                "message": "不存在借阅的记录"
            })
        if history.user_id != request.user.id and not request.user.is_superuser:
            return Response({
                "code": 4000,
                "type": "请求参数非法",
                "message": "非本人所借书籍，无法归还"
            })
        if history.status:
            return Response({
                "code": 4000,
                "type": "请求参数非法",
                "message": "书籍已被归还"
            })
        try:
            history.end = datetime.datetime.now()
            history.status = 1
            history.save()

            book = BookInfo.objects.get(id=history.book_id)
            book.number = book.number + 1
            book.save()

            request.user.borrowed += 1
            request.user.save()
        except:
            return Response({
                "code": 5000,
                "type": "服务器",
                "message": "操作数据库出错"
            }, status=500)
        return Response({
            "code": 0,
            "type": "访问成功",
            "message": "归还成功"
        })
